package com.sloan.community.provider;

import com.sloan.community.common.dto.GitHubUserDTO;
import com.sloan.community.exception.CommunityException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class GitHubProvider {

    @Value("${oauth2.github.access_token_url}")
    private String accessTokenUrl;

    @Value("${oauth2.github.user_info_url}")
    private String userInfoUrl;

    @Value("${oauth2.github.client_id}")
    private String clientId;

    @Value("${oauth2.github.client_secrets}")
    private String clientSecret;

    private final WebClient webClient;

    public Mono<GitHubUserDTO> fetchUserInfo(String code) {
        Map<String, Object> param = new HashMap<>();
        param.put("code", code);
        param.put("client_id", clientId);
        param.put("client_secret", clientSecret);

        Mono<GitHubUserDTO> stringMono = webClient.post()
                .uri(accessTokenUrl)
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .bodyValue(param)
                .retrieve()
                .bodyToMono(HashMap.class)
                .doOnNext(data -> {
                    log.info("从GitHub获取到accessToken数据:{}", data);
                })
                .map(item -> item.get("access_token"))
                .switchIfEmpty(Mono.error(CommunityException.of("GitHub第三方授权登录失败")))
                .onErrorResume(err -> Mono.error(CommunityException.of(err.getMessage())))
                .flatMap(token -> {
                    return webClient.get()
                            .uri(userInfoUrl)
                            .accept(MediaType.APPLICATION_JSON)
                            .header("Authorization", "Bearer " + token)
                            .retrieve()
                            .bodyToMono(Map.class)
                            .flatMap(entry -> {
                                log.info("获取到GITHUB用户的有关信息:{}",entry.toString());
                                String url = (String) entry.get("url");
                                return webClient.get()
                                        .uri(url)
                                        .accept(MediaType.APPLICATION_JSON)
                                        .retrieve()
                                        .bodyToMono(GitHubUserDTO.class);
                            });
                })
                .onErrorResume(err -> Mono.error(CommunityException.of("GitHub授权出现问题,请尝试切换其他登录方式登录!")));

        return stringMono.doOnNext(userInfo -> log.info("从Github获取到的用户信息:{}", userInfo));
    }
}
